package edu.zhuoxun.blogserver.configure;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import edu.zhuoxun.blogserver.entity.Permission;
import edu.zhuoxun.blogserver.entity.Role;
import edu.zhuoxun.blogserver.entity.User;
import edu.zhuoxun.blogserver.map.PermissionMapper;
import edu.zhuoxun.blogserver.map.RoleMapper;
import edu.zhuoxun.blogserver.map.UserMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.stream.Collectors;

@Component
public class MyRealm extends AuthorizingRealm {
    public final UserMapper userMapper;
    public final RoleMapper roleMapper;
    public final PermissionMapper permissionMapper;
    public MyRealm(UserMapper userMapper, RoleMapper roleMapper, PermissionMapper permissionMapper) {
        setName("Mybatis Plus Realm");
        this.userMapper = userMapper;
        this.roleMapper = roleMapper;
        this.permissionMapper = permissionMapper;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        Set<String> roleNames = roleMapper.getUserRole(user).stream().map(Role::getName).collect(Collectors.toSet());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
        Set<String> permissions = permissionMapper.getPermissionsByUser(user).stream().map(Permission::getName).collect(Collectors.toSet());
        info.setStringPermissions(permissions);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new UnknownAccountException();
        }
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }
}
